#!/usr/bin/env python
# -*- coding: utf-8 -*-

import logging
import re
from paramiko import SSHClient, AutoAddPolicy
import paramiko

class SSHCL:
    def __init__(self, source_ip, source_user, source_password, source_port, dest_ip, dest_user, dest_password, dest_port=22):
        self.source_ip = source_ip
        self.source_user = source_user
        self.source_password = source_password
        self.source_port = source_port
        self.dest_ip = dest_ip
        self.dest_user = dest_user
        self.dest_password = dest_password
        self.dest_port = dest_port

    def _connect_and_authenticate(self, client, host, port, user, password):
        client.set_missing_host_key_policy(AutoAddPolicy())
        try:
            client.connect(host, port, username=user, password=password, timeout=5)
            return True
        except (paramiko.AuthenticationException, paramiko.SSHException) as e:
            logging.error(f"Failed to connect/authenticate to {host}:{port}: {e}")
            return False

    def _execute_command(self, ssh_client, command):
        try:
            _, stdout, stderr = ssh_client.exec_command(command)
            output = stdout.read().decode().strip()
            error = stderr.read().decode().strip()
            if error:
                logging.warning(f"Error executing command '{command}': {error}")
            else:
                logging.info(output)
            return output
        except paramiko.SSHException as e:
            logging.error(f"Error executing command '{command}': {e}")

    def main(self):
        logging.basicConfig(
            level=logging.DEBUG,
            format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
            datefmt='%a, %d %b %Y %H:%M:%S',
            filename='ssh.log',
            filemode='w'
        )

        with SSHClient() as source_ssh:
            if not self._connect_and_authenticate(source_ssh, self.source_ip, self.source_port, self.source_user, self.source_password):
                return

            # 直接执行命令跳转到目标主机，而不是通过shell模拟交互
            # 这里假设目标主机已经在source主机的信任列表中，否则可能需要先执行`ssh-keyscan`并将结果写入source主机的known_hosts文件
            # 也可以考虑在程序中实现自动化信任主机密钥的功能
            tunnel_command = f'ssh -p {self.dest_port} {self.dest_user}@{self.dest_ip}'
            self._execute_command(source_ssh, tunnel_command)

            # 执行目标主机上的ifconfig命令
            ifconfig_command = 'ifconfig'
            result = self._execute_command(source_ssh, ifconfig_command)
            print(result)

if __name__ == '__main__':
    ssh = SSHCL('192.168.80.215', 'root', 'tenda123', 22, '192.168.80.216', 'root', 'tenda123')
    ssh.main()